/* ================================================================
solvling Ax = b for poisson equation, using KSP of PETSc package
ref: petsc-3.8.3/src/ksp/ksp/examples/tutorials/ex2.c
==================================================================*/
#ifdef enable_petsc

#ifndef SolverPetscKsp_H
#define SolverPetscKsp_H

#include <petscksp.h>

#include "Solver.h"
#include "Equation/Matrix.h"


class SolverPetscKsp : public Solver
{

public:

    SolverPetscKsp(math::SMatrix* A_, math::Vector* b_, math::Vector* x_);
    virtual ~SolverPetscKsp();

    virtual void operator()();
    void solve();
    void finish();
    void init();


    bool is_in_pestc_ksp_mpicomm()
    {
        if(petsc_ksp_mpi_rank < petsc_ksp_mpi_size)
        {
            return true;
        }
        else 
        {
            return false;
        }
    }

    math::SMatrix* A;
    math::Vector* b;
    math::Vector* x;

    WallTime* wall_time0;
    WallTime* wall_time1;

protected:

    double* x_temp;
    int nnz;
    int petsc_ksp_mpi_rank;
    int petsc_ksp_mpi_size;
    double petsc_ksp_tolerance_rtol;

    //======================== variables for PETSc_KSP ===================
    Vec            x_ksp,b_ksp,u_ksp;    /* approx solution, RHS, exact solution */
    Vec            x_seq;    /* global vector x */
    Mat            A_ksp;        /* linear system matrix */
    KSP            ksp;      /* linear solver context */
    PC             pc;       //PreCondition
    PetscRandom    rctx;     /* random number generator context */
    PetscReal      norm;     /* norm of solution error */
    PetscInt       I,J,Istart,Iend,its;
    PetscErrorCode ierr;
    PetscBool      flg = PETSC_FALSE;
    PetscScalar    v;
    PetscInt       *indices_global;
    VecScatter     ctx;







};

#endif

#endif